#include "InputManager.h"

InputManager::InputManager(std::string path)
{
	this->freopen(path);
}

void InputManager::clear()
{
	this->demand.close();
	this->site.close();
	this->qos.close();
	this->config.close();

	this->timeNum = this->clientNum = this->siteNum = this->qosLimit = 0;
	this->clientName.clear();
	this->bandwidthDemand.clear();
	this->siteName.clear();
	this->bandwidthLimit.clear();
}

void InputManager::freopen(std::string path)
{
	this->clear();

	if (path[path.size() - 1] != '\\' && path[path.size() - 1] != '/')
	{
		path += '/';
	}
	demand.open(path + "demand.csv", std::ios::in);
	if (!demand.good())
	{
		std::cerr << "[InputManager Error]freopen(std::string path):Open demand.csv Error!\n";
		exit(0);
	}

	site.open(path + "site_bandwidth.csv", std::ios::in);
	if (!site.good())
	{
		std::cerr << "[InputManager Error]freopen(std::string path):Open site_bandwidth.csv Error!\n";
		exit(0);
	}
	qos.open(path + "qos.csv", std::ios::in);
	if (!qos.good())
	{
		std::cerr << "[InputManager Error]freopen(std::string path):Open qos.csv Error!\n";
		exit(0);
	}
	config.open(path + "config.ini", std::ios::in);
	if (!config.good())
	{
		std::cerr << "[InputManager Error]freopen(std::string path):Open config.ini Error!\n";
		exit(0);
	}

	this->getDemand(this->timeNum, this->clientNum, this->clientName, this->bandwidthDemand);
	this->getSite(this->siteNum, this->siteName, this->bandwidthLimit);
	this->getQosLimit(this->qosLimit);
	
	return;
}
void InputManager::getDemand(int& timeNum, int& clientNum, std::vector<std::string>& clientName, std::vector<std::vector<int>>& bandwidthDemand)
{
	std::string line;
	std::stringstream stream;
	std::string tmpString;


	std::getline(demand, line);
	stream << line;
	std::getline(stream, tmpString, ',');

	clientNum = 0;
	clientName.push_back("");
	while (std::getline(stream, tmpString, ','))
	{
		++clientNum;
		std::replace(tmpString.begin(), tmpString.end(), '\n', '\0');  //maybe have big bug
		std::replace(tmpString.begin(), tmpString.end(), '\r', '\0');  //maybe have big bug
		tmpString = std::string(tmpString.c_str());
		clientName.push_back(tmpString);
	}

	timeNum = 0;
	bandwidthDemand.push_back(std::vector<int>{});
	while (std::getline(demand, line))
	{
		++timeNum;
		stream.clear();
		stream << line;
		std::getline(stream, tmpString, ',');
		std::vector<int> nowTime;
		nowTime.push_back(0);
		while (std::getline(stream, tmpString, ','))
		{
			nowTime.push_back(std::stoi(tmpString));
		}
		bandwidthDemand.push_back(nowTime);
	}

}

void InputManager::getSite(int& siteNum, std::vector<std::string>& siteName, std::vector<int>& bandwidthLimit)
{
	std::string line;
	std::stringstream stream;
	std::string tmpString;

	std::getline(site, line);

	siteNum = 0;
	siteName.push_back("");
	bandwidthLimit.push_back(0);
	while (std::getline(site, line))
	{
		++siteNum;
		stream.clear();
		stream << line;

		std::getline(stream, tmpString, ',');
		siteName.push_back(tmpString);
		std::getline(stream, tmpString, ',');
		bandwidthLimit.push_back(std::stoi(tmpString));
	}

}

void InputManager::getQosLimit(int& qosLimit)
{
	std::string line;
	std::stringstream stream;
	std::string tmpString;

	std::getline(config, line);
	std::getline(config, line);
	stream << line;
	std::getline(stream, tmpString, '=');
	std::getline(stream, tmpString, '=');
	qosLimit = std::stoi(tmpString);
}

void InputManager::getQosGraph(std::vector<std::pair<int, int>>& graph)
{
	std::string line;
	std::stringstream stream;
	std::string tmpString;	

	graph.push_back(std::make_pair(0, 0));
	std::getline(qos, line);
	int row = 0, col = 0;
	while (std::getline(qos, line))
	{
		++row;
		col = 0;
		stream.clear();
		stream << line;
		std::getline(stream, tmpString, ',');
		while (std::getline(stream, tmpString, ','))
		{
			++col;
			if (qosLimit > std::stoi(tmpString)) 
				graph.push_back(std::make_pair(row, col));

		}
	}
}

int InputManager::getTotalTime()
{
	return this->timeNum;
}

void InputManager::getDemands(int timeID, std::vector<int>& bandwidthDemand)
{
	bandwidthDemand = this->bandwidthDemand[timeID];
}

void InputManager::getSiteLimits(std::vector<int>& bandwidthLimit)
{
	bandwidthLimit = this->bandwidthLimit;
}

void InputManager::getQosGraph(int& siteNum, int& clientNum, std::vector<std::pair<int, int>>& graph)
{
	siteNum = this->siteNum;
	clientNum = this->clientNum;
	this->getQosGraph(this->graphSiteToClient);
	graph = this->graphSiteToClient;
}